﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;

namespace Connector
{
    public class Logger
    {
        /// <summary>
        /// intern file tracer for singelton
        /// </summary>
        private static TextWriterTraceListener _fileTracer;

        /// <summary>
        /// instance for text file tracing.
        /// </summary>
        public static TextWriterTraceListener FileTracer
        {
            get
            {
                if (_fileTracer == null)
                    if (String.IsNullOrEmpty(FileName))
                        _fileTracer = new TextWriterTraceListener("Trace.Log");
                    else
                        _fileTracer = new TextWriterTraceListener(FileName);

                return _fileTracer;
            }
        }

        /// <summary>
        /// path and file name of the log file.
        /// </summary>
        public static string FileName { get; set; }

        /// <summary>
        /// Level for tracing.
        /// </summary>
        public static TraceLevel TraceLevel { get; set; }

        /// <summary>
        /// Logs a given message as error containing a time stamp.
        /// </summary>
        /// <param name="message">Message to log.</param>
        public static void LogError(string message)
        {
            if (TraceLevel >= TraceLevel.Error)
            {
                FileTracer.WriteLine(message, String.Format("Error {0:yyyy-MM-dd HH:mm:ss.ffffzzz}", DateTime.Now));
                FileTracer.Flush();
            }
        }

        /// <summary>
        /// Logs a given exception including stack trace as error containing a time stamp.
        /// </summary>
        /// <param name="message">Message to log.</param>
        public static void LogError(Exception ex)
        {
            LogError(CreateExceptionMessage(ex));
        }

        /// <summary>
        /// Logs a given message as warning containing a time stamp.
        /// </summary>
        /// <param name="message">Message to log.</param>
        public static void LogWarning(string message)
        {
            if (TraceLevel >= TraceLevel.Warning)
            {
                FileTracer.WriteLine(message, String.Format("Warning {0:yyyy-MM-dd hh:mm:ss.ffffzzz}", DateTime.Now));
                FileTracer.Flush();
            }
        }

        /// <summary>
        /// Logs a given message as information containing a time stamp.
        /// </summary>
        /// <param name="message">Message to log.</param>
        public static void LogInformation(string message)
        {
            if (TraceLevel >= TraceLevel.Info)
            {
                FileTracer.WriteLine(message, String.Format("Info {0:yyyy-MM-dd hh:mm:ss.ffffzzz}", DateTime.Now));
                FileTracer.Flush();
            }
        }

        /// <summary>
        /// Retruns a message string containing all messages from the inner exceptions.
        /// </summary>
        /// <param name="ex">Exception to get the Messages of.</param>
        /// <returns>String with all messages and inner exception messages.</returns>
        public static string CreateExceptionMessage(Exception ex)
        {
            StringBuilder messages = new StringBuilder(ex.Message);
            Exception tmpException = ex.InnerException;
            while (tmpException != null)
            {
                messages.Append("\r\n\t");
                messages.Append(tmpException.Message);
                tmpException = tmpException.InnerException;
            }

            messages.Append("\r\n   StackTrace:\r\n");
            messages.Append(ex.StackTrace);
            return messages.ToString();
        }
    }
}
